package com.briup.es.web.interceptor;

import com.briup.es.config.auth.TokenMap;
import com.briup.es.config.auth.UserDetails;
import com.briup.es.config.exception.ServiceException;
import com.briup.es.config.response.ResultCode;
import com.briup.es.domain.bean.User;
import com.briup.es.service.UserService;
import com.briup.es.utils.JwtUtil;
import org.springframework.stereotype.Component;
import org.springframework.web.servlet.HandlerInterceptor;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

/**
 * 用于登录认证的拦截器
 */
@Component
public class AuthInterceptor implements HandlerInterceptor {

    @Resource
    private UserService userService;

    // 在请求进入到Controller方法之前，将请求拦截，查看请求中是否携带token
    // 以及其携带的token是否有效
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        // 如果请求的方式为 OPTIONS，那么本请求为跨域的预请求，需要直接放行
        if ("OPTIONS".equals(request.getMethod())) {
            return true;
        }
        // 从请求头中获取token
        String token = request.getHeader("token");
        // 解析token，从中获取当前登录用户的id
        Integer userId = JwtUtil.fieldValue(token, "userId", Integer.class);

        // 获取TokenMap中的token
        String innerToken = TokenMap.get(userId);
        if (!token.equals(innerToken)) {
            // 如果用户传入的token与服务器内部维护的token不一致，那说明token被冒用了，
            // 需要重新登录
            throw new ServiceException(ResultCode.TOKEN_IS_INVALID);
        }

        // 根据用户id查询用户信息
        User user = userService.queryById(userId);
        UserDetails.setCurrentUser(user);

        return true;
    }

    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
        UserDetails.clear();
    }
}
